package com.jdk8.lambda;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class LambdaDesc {
	/**
	 * Lambda表达式：一种用来表示匿名内部类和闭包的运算符。
	 * Java中，Lambda表达式是对象，它们必须依附于一类特别的对象类型——函数式接口(Functional Interface)
	 * 函数式接口：在Java定义的借口中有且只有一个抽象的方法（不包括Object类里的方法）
	 * Java8后，Runnable接口多了一个FunctionalInterface注解，表示该接口是一个函数式接口；
	 * 但是如果我们不添加FunctionalInterface注解的话，如果接口中有且只有一个抽象方法时，编译器也会把该接口当做函数式接口看待。
	 * Java8中，接口里面的方法不仅仅只能有抽象方法，也可以有具体实现了的方法，被称作默认方法(default method) /
	 * 
	 * 
	 * 
	 * /**Lambda表达式格式： （param1,param2,param3....） -> { //go to } 只有一个参数的情况下，小括号可以省略
	 * go to方法体只有一行代码时，可以省略{}
	 */

	/**
	 * 函数式接口实例的创建可以有三种方式（参考自FunctionalInterface注解说明）：
	 * 1.Lambda表达式：lambda表达式的入参和返回必须符合这个函数式接口中唯一的抽象方法的定义,
	 *      例如：list.forEach(item ->  System.out.println(item)); 
	 * 2.方法引用：格式--->对象 ：：方法名,也必须遵守方法的定义， 
	 *      例如：list.forEach(System.out::println);
	 *  3.构造方法引用：格式--->类名::new,必须要符合抽象方法的方法定义 
	 *     例如：list.forEach(LambdaDesc::new);
	 *   
	 */
     
	/**
	 * java8内置的函数式接口：
	 * Supplier：直接获取对象
	 * Predicate：传入一个参数，返回boolean值
	 * Function：传入一个参数，返回另一结果
	 * Consumer：消费着，传入参数
	 */
	private String desc;

	public LambdaDesc(String desc) {
		this.desc = desc;
		System.out.println("desc="+desc);
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}
    
	public static void main(String[] args) {
		List<String> strList=Arrays.asList("周一","周二","周三","周三","周五");
//		//第一种：Lambda表达式创建函数式接口实例
//		strList.forEach(obs -> System.out.println(obs));
//		//第二种：方法引用来创建函数式接口实例
//		System.out.println("=========================");
//		strList.forEach(LambdaDesc::descValue);
//		//第三种：构造函数来创建函数式接口实例
//		System.out.println("=========================");
//		strList.forEach(LambdaDesc::new);
		
//		System.out.println(compute(2, n -> n+2));
		Supplier<String> supplier = String::new;
//        String s = supplier.get();
//        Predicate<Integer> res=it ->it>0;
//        System.out.println("s="+res.test(-1));
        Predicate<String> preStr=s ->s.equals("周三");
        List<String> strs=conditionFilter(strList,preStr);
        strs.forEach(LambdaDesc::new);
	}
	
	public static void descValue(String value) {
		System.out.println("input value="+value);
	}
	
	public static int compute(Integer i,Function<Integer, Integer> fn) {
		return fn.apply(i);
	}
	
	public static List<String> conditionFilter(List<String> list,Predicate<String> predicate){
		return list.stream().filter(predicate).collect(Collectors.toList());
	}
	
	
	
}
